#ifndef STIMULUS_H
#define STIMULUS_H

#include <set>
#include <map>

class Stimulus
{
public:
	Stimulus()
		:mTag(0)
	{}
	virtual ~Stimulus()
	{}
	Stimulus& SetTag(int inTag)
	{
		mTag = inTag; return *this;
	}
	int Tag() const
	{ return mTag; }

	// Event calling interface
	Stimulus& Present()
	{ OnPresent(); return *this; }
	Stimulus& Conceal()
	{ OnConceal(); return *this; }

protected:
	virtual void OnPresent() = 0;
	virtual void OnConceal() = 0;

private:
	int mTag;
};

class SetOfStimulus : public std::set<Stimulus*>
{
public:
	SetOfStimulus()
	{}
	virtual ~SetOfStimulus()
	{}
	//HouseHolding
	SetOfStimulus& Add(Stimulus* s)
	{
		insert(s); return *this;
	}
	SetOfStimulus& Remove(Stimulus* s)
	{
		erase(s); return *this;
	}
	SetOfStimulus& Clear()
	{
		clear(); return *this;
	}
	SetOfStimulus& DeleteObjects()
	{
		for(iterator i = begin(); i!=end(); ++i)
			delete (*i);
		clear();
		return *this;
	}

	bool Contains(Stimulus* s) const
	{
		return find(s) != end();
	}

	bool Intersects(const SetOfStimulus&  s) const
	{
		for(const_iterator i = begin(); i!=end(); i++)
			if(s.Contains(*i)) return true;
		return false;
	}

	//Events
	void Present()
	{
		for(iterator i=begin(); i!=end(); ++i)
			(*i)->Present();
	}
	void Conceal()
	{
		for(iterator i=begin(); i!=end(); ++i)
			(*i)->Conceal();
	}
};

#endif